package com.blog.cmrpersonalblog.controller;

import cn.dev33.satoken.annotation.SaCheckRole;
import com.blog.cmrpersonalblog.common.Result;
import com.blog.cmrpersonalblog.dto.ranking.requset.RankingRequest;
import com.blog.cmrpersonalblog.dto.ranking.respnose.RankingResponse;
import com.blog.cmrpersonalblog.enums.RankingDimension;
import com.blog.cmrpersonalblog.enums.RankingType;
import com.blog.cmrpersonalblog.service.RankingService;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * 排行榜控制器（重构版）
 * 支持文章榜、作者榜、收藏榜的查询和管理
 */
@Slf4j
@RestController
@RequestMapping("/api/ranking")
@CrossOrigin(origins = "*", maxAge = 3600)
@Validated
public class RankingController {

    @Resource
    private RankingService rankingService;

    // ==================== 公开接口 ====================

    /**
     * 查询榜单
     * 支持文章榜、作者榜、收藏榜
     * 支持综合榜和分类榜
     */
    @GetMapping("/list")
    public Result<RankingResponse> getRanking(@Valid RankingRequest request) {
        log.info("查询榜单: {}", request);
        try {
            RankingResponse response = rankingService.getRanking(request);
            return Result.success("查询榜单成功", response);
        } catch (IllegalArgumentException e) {
            log.warn("查询榜单参数错误: {}", e.getMessage());
            return Result.error(e.getMessage());
        } catch (Exception e) {
            log.error("查询榜单失败", e);
            return Result.error("查询榜单失败：" + e.getMessage());
        }
    }

    /**
     * 获取文章榜（综合）
     */
    @GetMapping("/article/overall")
    public Result<RankingResponse> getArticleOverallRanking(
            @RequestParam(defaultValue = "1") Long current,
            @RequestParam(defaultValue = "50") Long size) {
        RankingRequest request = new RankingRequest();
        request.setRankingType("ARTICLE");
        request.setDimension("OVERALL");
        request.setCurrent(current);
        request.setSize(size);
        return getRanking(request);
    }

    /**
     * 获取文章榜（分类）
     */
    @GetMapping("/article/category/{categoryId}")
    public Result<RankingResponse> getArticleCategoryRanking(
            @PathVariable Long categoryId,
            @RequestParam(defaultValue = "1") Long current,
            @RequestParam(defaultValue = "50") Long size) {
        RankingRequest request = new RankingRequest();
        request.setRankingType("ARTICLE");
        request.setDimension("CATEGORY");
        request.setCategoryId(categoryId);
        request.setCurrent(current);
        request.setSize(size);
        return getRanking(request);
    }

    /**
     * 获取作者榜（综合）
     */
    @GetMapping("/author/overall")
    public Result<RankingResponse> getAuthorOverallRanking(
            @RequestParam(defaultValue = "1") Long current,
            @RequestParam(defaultValue = "50") Long size) {
        RankingRequest request = new RankingRequest();
        request.setRankingType("AUTHOR");
        request.setDimension("OVERALL");
        request.setCurrent(current);
        request.setSize(size);
        return getRanking(request);
    }

    /**
     * 获取作者榜（分类）
     */
    @GetMapping("/author/category/{categoryId}")
    public Result<RankingResponse> getAuthorCategoryRanking(
            @PathVariable Long categoryId,
            @RequestParam(defaultValue = "1") Long current,
            @RequestParam(defaultValue = "50") Long size) {
        RankingRequest request = new RankingRequest();
        request.setRankingType("AUTHOR");
        request.setDimension("CATEGORY");
        request.setCategoryId(categoryId);
        request.setCurrent(current);
        request.setSize(size);
        return getRanking(request);
    }

    /**
     * 获取收藏榜（综合）
     */
    @GetMapping("/collection/overall")
    public Result<RankingResponse> getCollectionOverallRanking(
            @RequestParam(defaultValue = "1") Long current,
            @RequestParam(defaultValue = "50") Long size) {
        RankingRequest request = new RankingRequest();
        request.setRankingType("COLLECTION");
        request.setDimension("OVERALL");
        request.setCurrent(current);
        request.setSize(size);
        return getRanking(request);
    }

    /**
     * 获取收藏榜（分类）
     */
    @GetMapping("/collection/category/{categoryId}")
    public Result<RankingResponse> getCollectionCategoryRanking(
            @PathVariable Long categoryId,
            @RequestParam(defaultValue = "1") Long current,
            @RequestParam(defaultValue = "50") Long size) {
        RankingRequest request = new RankingRequest();
        request.setRankingType("COLLECTION");
        request.setDimension("CATEGORY");
        request.setCategoryId(categoryId);
        request.setCurrent(current);
        request.setSize(size);
        return getRanking(request);
    }

    /**
     * 获取指定目标的排名
     */
    @GetMapping("/rank")
    public Result<Map<String, Object>> getRank(
            @RequestParam String rankingType,
            @RequestParam String dimension,
            @RequestParam Long targetId,
            @RequestParam(required = false) Long categoryId) {
        log.info("查询排名: type={}, dimension={}, targetId={}, categoryId={}",
            rankingType, dimension, targetId, categoryId);
        try {
            RankingType type = RankingType.valueOf(rankingType);
            RankingDimension dim = RankingDimension.valueOf(dimension);

            Long rank = rankingService.getRank(type, dim, targetId, categoryId);

            Map<String, Object> result = new HashMap<>();
            result.put("rankingType", rankingType);
            result.put("dimension", dimension);
            result.put("targetId", targetId);
            result.put("categoryId", categoryId);
            result.put("rank", rank);
            result.put("inRanking", rank != null && rank > 0);

            return Result.success("查询排名成功", result);
        } catch (IllegalArgumentException e) {
            return Result.error("参数错误：" + e.getMessage());
        } catch (Exception e) {
            log.error("查询排名失败", e);
            return Result.error("查询排名失败：" + e.getMessage());
        }
    }

    // ==================== 管理接口 ====================

    /**
     * 刷新所有榜单（管理员）
     */
    @PostMapping("/admin/refresh/all")
    @SaCheckRole("admin")
    public Result<Void> refreshAllRankings() {
        log.info("管理员手动刷新所有榜单");
        try {
            rankingService.refreshAllRankings();
            return Result.success("所有榜单刷新成功");
        } catch (Exception e) {
            log.error("刷新所有榜单失败", e);
            return Result.error("刷新所有榜单失败：" + e.getMessage());
        }
    }

    /**
     * 刷新指定榜单（管理员）
     */
    @PostMapping("/admin/refresh")
    @SaCheckRole("admin")
    public Result<Void> refreshRanking(
            @RequestParam String rankingType,
            @RequestParam String dimension,
            @RequestParam(required = false) Long categoryId) {
        log.info("管理员刷新榜单: type={}, dimension={}, categoryId={}",
            rankingType, dimension, categoryId);
        try {
            RankingType type = RankingType.valueOf(rankingType);
            RankingDimension dim = RankingDimension.valueOf(dimension);

            rankingService.refreshRanking(type, dim, categoryId);
            return Result.success("榜单刷新成功");
        } catch (IllegalArgumentException e) {
            return Result.error("参数错误：" + e.getMessage());
        } catch (Exception e) {
            log.error("刷新榜单失败", e);
            return Result.error("刷新榜单失败：" + e.getMessage());
        }
    }

    /**
     * 更新榜单项（管理员）
     */
    @PostMapping("/admin/update")
    @SaCheckRole("admin")
    public Result<Void> updateRankingItem(
            @RequestParam String rankingType,
            @RequestParam Long targetId) {
        log.info("管理员更新榜单项: type={}, targetId={}", rankingType, targetId);
        try {
            RankingType type = RankingType.valueOf(rankingType);
            rankingService.updateRankingItem(type, targetId);
            return Result.success("榜单项更新成功");
        } catch (IllegalArgumentException e) {
            return Result.error("参数错误：" + e.getMessage());
        } catch (Exception e) {
            log.error("更新榜单项失败", e);
            return Result.error("更新榜单项失败：" + e.getMessage());
        }
    }

    /**
     * 从榜单中移除项（管理员）
     */
    @DeleteMapping("/admin/remove")
    @SaCheckRole("admin")
    public Result<Void> removeFromRanking(
            @RequestParam String rankingType,
            @RequestParam Long targetId) {
        log.info("管理员从榜单移除项: type={}, targetId={}", rankingType, targetId);
        try {
            RankingType type = RankingType.valueOf(rankingType);
            rankingService.removeFromRanking(type, targetId);
            return Result.success("已从榜单移除");
        } catch (IllegalArgumentException e) {
            return Result.error("参数错误：" + e.getMessage());
        } catch (Exception e) {
            log.error("从榜单移除失败", e);
            return Result.error("从榜单移除失败：" + e.getMessage());
        }
    }

    /**
     * 清空所有榜单（管理员）
     */
    @PostMapping("/admin/clear")
    @SaCheckRole("admin")
    public Result<Void> clearAllRankings() {
        log.info("管理员清空所有榜单");
        try {
            rankingService.clearAllRankings();
            return Result.success("所有榜单已清空");
        } catch (Exception e) {
            log.error("清空榜单失败", e);
            return Result.error("清空榜单失败：" + e.getMessage());
        }
    }

    /**
     * 获取榜单统计信息（管理员）
     */
    @GetMapping("/admin/statistics")
    @SaCheckRole("admin")
    public Result<RankingService.RankingStatistics> getStatistics() {
        log.info("获取榜单统计信息");
        try {
            RankingService.RankingStatistics statistics = rankingService.getStatistics();
            return Result.success("获取统计信息成功", statistics);
        } catch (Exception e) {
            log.error("获取统计信息失败", e);
            return Result.error("获取统计信息失败：" + e.getMessage());
        }
    }

    /**
     * 获取榜单健康状态（管理员）
     */
    @GetMapping("/admin/health")
    @SaCheckRole("admin")
    public Result<Map<String, Object>> getHealth() {
        log.info("检查榜单健康状态");
        try {
            Map<String, Object> health = new HashMap<>();

            RankingService.RankingStatistics stats = rankingService.getStatistics();
            health.put("statistics", stats);
            health.put("lastUpdateTime", stats.getLastUpdateTime());
            health.put("nextUpdateTime", rankingService.getNextUpdateTime());
            health.put("status", "healthy");
            health.put("checkTime", LocalDateTime.now().format(
                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

            return Result.success("健康检查完成", health);
        } catch (Exception e) {
            log.error("健康检查失败", e);
            Map<String, Object> health = new HashMap<>();
            health.put("status", "unhealthy");
            health.put("error", e.getMessage());
            health.put("checkTime", LocalDateTime.now().format(
                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            return Result.error("健康检查失败：" + e.getMessage());
        }
    }
}
